package com.xiyu.service.service.bed;

import com.xiyu.service.repository.bed.room.RoomTypeRepository;
import com.xiyu.service.vo.bed.buildingInfo.BuildingInfoListQueryOutput;
import com.xiyu.service.vo.bed.buildingInfo.BuildingInfoUpdateInput;
import com.xiyu.service.model.bed.building.BuildingInfo;
import com.xiyu.service.repository.bed.building.BuildingInfoRepository;
import com.xiyu.service.vo.bed.buildingInfo.BuildingInfoQueryOutput;
import com.xiyu.service.vo.bed.buildingInfo.BuildingInfoQueryInput;
import com.xiyu.service.vo.bed.buildingInfo.BuildingInfoGetOutput;
import com.xiyu.service.vo.bed.buildingInfo.BuildingInfoCreateInput;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.babyfish.jimmer.Page;
import java.util.*;

import org.springframework.transaction.annotation.Transactional;
import com.xiyu.service.framework.web.web.core.pojo.PageResult;
import com.xiyu.service.convert.bed.BuildingInfoConvert;

import static com.xiyu.service.framework.exception.util.ServiceExceptionUtil.exception;
import static com.xiyu.service.errorCode.bed.BuildingInfoErrorCode.*;

/**
 * 楼栋信息 Service 实现类
 */
@Service
@Validated
public class BuildingInfoServiceImpl implements BuildingInfoService {

    @Resource
    private RoomTypeRepository roomTypeRepository;


    @Resource
    private BuildingInfoRepository buildingInfoRepository;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long create(BuildingInfoCreateInput inputVO) {
        Optional<BuildingInfo> opBuilding = buildingInfoRepository.findFirstByBuildingName(inputVO.getBuildingName());
        if(opBuilding.isPresent())
            throw exception(BUILDING_EXIST);
        BuildingInfo newBuilding = buildingInfoRepository.insert(BuildingInfoConvert.INSTANCE.createInputConvert(inputVO));
        return newBuilding.id();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean update(BuildingInfoUpdateInput inputVO) {
        Optional<BuildingInfo> opOldBuilding = buildingInfoRepository.findFirstByBuildingNameAndIdNot(inputVO.getBuildingName(), inputVO.getId());
        if(opOldBuilding.isPresent())
            throw exception(BUILDING_EXIST);
        buildingInfoRepository.update(BuildingInfoConvert.INSTANCE.updateInputConvert(inputVO));
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleted(Long id) {
        Optional<BuildingInfo> opDeleteBuilding = buildingInfoRepository.findById(id);
        if(!opDeleteBuilding.isPresent())
            throw exception(BUILDING_NOT_EXIST);
        if(opDeleteBuilding.get().floorNumber() > 1005000000)
            throw exception(BUILDING_NOT_EMPTY_FLOOR);
        buildingInfoRepository.deleteById(id);
        return true;
    }

    @Override
    public BuildingInfoGetOutput get(Long id) {
        Optional<BuildingInfo> opBuilding = buildingInfoRepository.findById(id);
        if(!opBuilding.isPresent())
            throw exception(BUILDING_NOT_EXIST);
        return BuildingInfoConvert.INSTANCE.getOutputConvert(opBuilding.get());
    }

    @Override
    public PageResult<BuildingInfoQueryOutput> query(BuildingInfoQueryInput inputVO) {
        Page<BuildingInfo> buildingInfoPage = buildingInfoRepository.pageQuery(inputVO);
        List<BuildingInfoQueryOutput> buildingInfos = BuildingInfoConvert.INSTANCE.queryPageOutputConvert(buildingInfoPage.getRows());
        return new PageResult<>(buildingInfos, buildingInfoPage.getTotalRowCount());
    }

    @Override
    public List<BuildingInfoListQueryOutput> listQuery() {
        List<BuildingInfo> listBuildingInfo = buildingInfoRepository.findAll();
        return BuildingInfoConvert.INSTANCE.listQueryOutputConvert(listBuildingInfo);

    }

}
